# +----------------------------------------------------------------------
# | ChatWork智能聊天办公系统
# +----------------------------------------------------------------------
# | 软件声明: 本系统并非自由软件,未经授权任何形式的商业使用均属非法。
# | 版权保护: 任何企业和个人不允许对程序代码以任何形式任何目的复制/分发。
# | 授权要求: 如有商业使用需求,请务必先与版权所有者取得联系并获得正式授权。
# +----------------------------------------------------------------------
# | Author: ChatWork Team <2474369941@qq.com>
# +----------------------------------------------------------------------
import time
from typing import List
from pydantic import TypeAdapter
from hypertext import PagingResult
from exception import AppException
from common.models.auth import AuthAdminModel
from common.models.auth import AuthRoleModel
from common.models.auth import AuthPermModel
from apps.admin.cache.login_cache import LoginCache
from apps.admin.schemas.auth import role_schema as schema


class RoleService:
    """ 系统角色服务类 """

    @classmethod
    async def whole(cls) -> List[schema.AuthRoleWholeVo]:
        """
        所有角色。

        Returns:
            List[schema.AuthRoleWholeVo]: 所有角色列表。

        Author:
            zero
        """
        _lists = await AuthRoleModel\
            .filter(is_delete=0)\
            .order_by("-sort", "-id")\
            .all()\
            .values("id", "name", "is_disable")

        return [TypeAdapter(schema.AuthRoleWholeVo).validate_python(item) for item in _lists]

    @classmethod
    async def lists(cls, params: schema.AuthRoleSearchIn) -> PagingResult[schema.AuthRoleListVo]:
        """
        角色列表。

        Args:
            params (schema.AuthRoleSearchIn): 角色查询参数。

        Returns:
            PagingResult[schema.AuthRoleListVo]: 角色分页列表Vo。

        Author:
            zero
        """
        _model = AuthRoleModel.filter(is_delete=0).order_by("-sort", "-id")
        _pager = await AuthRoleModel.paginate(
            model=_model,
            page_no=params.page_no,
            page_size=params.page_size,
            schema=schema.AuthRoleListVo,
            fields=AuthRoleModel.without_field("is_delete,delete_time"),
        )

        for item in _pager.lists:
            item.admin_sum = await AuthAdminModel.filter(role_id=item.id, is_delete=0).count()

        return _pager

    @classmethod
    async def detail(cls, id_: int) -> schema.AuthRoleDetailVo:
        """
        角色详情。

        Args:
            id_ (int): 角色ID。

        Returns:
            AuthRoleDetailVo: 角色详情Vo。

        Author:
            zero
        """
        role = await AuthRoleModel.get(id=id_)

        perms = await AuthPermModel.filter(role_id=role.id).all()
        menu_ids = [item.menu_id for item in perms]

        detail = role.__dict__
        detail["menu_ids"] = menu_ids
        return TypeAdapter(schema.AuthRoleDetailVo).validate_python(detail)

    @classmethod
    async def add(cls, post: schema.AuthRoleAddIn):
        """
        角色新增。

        Args:
            post (schema.AuthRoleAddIn): 角色新增参数。

        Author:
            zero
        """
        params = post.dict()
        del params["menu_ids"]

        role = await AuthRoleModel.create(
            **params,
            create_time=int(time.time()),
            update_time=int(time.time())
        )

        if post.menu_ids:
            for mid in post.menu_ids:
                await AuthPermModel.create(role_id=role.id, menu_id=mid)

        await LoginCache.role_perms_del()

    @classmethod
    async def edit(cls, post: schema.AuthRoleEditIn):
        """
        角色编辑。

        Args:
            post (schema.AuthRoleEditIn): 角色编辑参数。

        Author:
            zero
        """
        params = post.dict()
        del params["id"]
        del params["menu_ids"]

        await AuthRoleModel.filter(id=post.id).update(
            **params,
            create_time=int(time.time()),
            update_time=int(time.time())
        )

        await AuthPermModel.filter(role_id=post.id).delete()
        if post.menu_ids:
            for mid in post.menu_ids:
                await AuthPermModel.create(role_id=post.id, menu_id=mid)

        await LoginCache.role_perms_del()

    @classmethod
    async def delete(cls, id_: int):
        """
        角色删除。

        Args:
            id_ (int): 角色ID。

        Author:
            zero
        """
        role = await AuthRoleModel.filter(id=id_, is_delete=0).first()
        if not role:
            raise AppException("角色不存在")

        admin = await AuthAdminModel.filter(role_id=id_, is_delete=0).first()
        if admin:
            raise AppException("角色已被使用不能删除")

        await AuthRoleModel.filter(id=id_).update(is_delete=1, delete_time=int(time.time()))
        await LoginCache.role_perms_del()
